package at.xtools.pwawrapper.webview;

import at.xtools.pwawrapper.Constants;
import at.xtools.pwawrapper.ResourceTable;
import at.xtools.pwawrapper.ui.UIManager;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.webengine.*;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.PixelMap;
import ohos.net.NetCapabilities;
import ohos.net.NetManager;
import ohos.utils.net.Uri;

public class WebViewHelper {
    // Instance variables
    private Ability activity;
    private UIManager uiManager;
    private WebView webView;
    private WebConfig webSettings;

    private static WebView sWebView;

    static public WebView getWebView(Ability activity) {
        if (sWebView == null) {
            sWebView = new WebView(activity);
        }
        return sWebView;
    }

    private String currentUrl;

    private HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x00, "WebViewHelper");

    public WebViewHelper(Ability activity, UIManager uiManager) {
        this.activity = activity;
        this.uiManager = uiManager;
        this.webView = (WebView) activity.findComponentById(ResourceTable.Id_webView);
//        this.webView = getWebView(activity);
        this.webSettings = webView.getWebConfig();
    }

    /**
     * Simple helper method checking if connected to Network.
     * Doesn't check for actual Internet connection!
     *
     * @return {boolean} True if connected to Network.
     */
    private boolean isNetworkAvailable() {
        NetManager netManager = NetManager.getInstance(activity);
        NetCapabilities netCapabilities = netManager.getNetCapabilities(netManager.getDefaultNet());
        // NetCapabilities.NET_CAPABILITY_VALIDATED表示连接了网络，并且可以上网
        return netCapabilities.hasCap(NetCapabilities.NET_CAPABILITY_VALIDATED);
    }

    // manipulate cache settings to make sure our PWA gets updated
    private void useCache(Boolean use) {
    }

    // public method changing cache settings according to network availability.
    // retrieve content from cache primarily if not connected,
    // allow fetching from web too otherwise to get updates.
    public void forceCacheIfOffline() {
        useCache(!isNetworkAvailable());
    }

    // handles initial setup of webview
    public void setupWebView() {
        // enable JS
        webSettings.setJavaScriptPermit(true);
        // retrieve content from cache primarily if not connected
        forceCacheIfOffline();

        // set User Agent
        if (Constants.OVERRIDE_USER_AGENT || Constants.POSTFIX_USER_AGENT) {
            String userAgent = webSettings.getUserAgent();
            if (Constants.OVERRIDE_USER_AGENT) {
                userAgent = Constants.USER_AGENT;
            }
            if (Constants.POSTFIX_USER_AGENT) {
                userAgent = userAgent + " " + Constants.USER_AGENT_POSTFIX;
            }
            webSettings.setUserAgent(userAgent);
        }

        // enable HTML5-support
        webView.setBrowserAgent(new BrowserAgent(activity) {
            @Override
            public boolean onJsMessageShow(WebView webView, String url, String message, boolean isAlert, JsMessageResult result) {
                return false;
            }

            // update ProgressBar
            @Override
            public void onProgressUpdated(WebView view, int newProgress) {
                uiManager.setLoadingProgress(newProgress);
                super.onProgressUpdated(view, newProgress);
            }
        });

        // Set up Webview client
        webView.setWebAgent(new WebAgent() {
            @Override
            public void onLoadingPage(WebView view, String url, PixelMap favicon) {
                super.onLoadingPage(view, url, favicon);
                handleUrlLoad(view, url);
                currentUrl = url;
            }

            @Override
            public void onError(WebView view, ResourceRequest request, ResourceError error) {
                // we only want to interfere if the page itself got problems.
            }
        });
    }

    // Lifecycle callbacks
    public void onPause() {
        webView.onInactive();
    }

    public void onResume() {
        webView.onActive();
    }

    // show "no app found" dialog
    private void showNoAppDialog(Ability thisActivity) {
    }

    // handle load errors
    private void handleLoadError(int errorCode) {
        if (errorCode != -10) {
            uiManager.setOffline(true);
        } else {
            // Unsupported Scheme, recover
            new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
                @Override
                public void run() {
                    goBack();
                }
            }, 100);
        }
    }

    // handle external urls
    private boolean handleUrlLoad(WebView view, String url) {
        // prevent loading content that isn't ours
        if (!url.startsWith(Constants.WEBAPP_URL)) {
            view.getNavigator().goBack();
            // open external URL in Browser/3rd party apps instead
            try {
                Intent intent = new Intent();
                intent.setAction("android.intent.action.VIEW");
                intent.setUri(Uri.parse(url));
                activity.startAbility(intent);
            } catch (Exception e) {
            }
            // return value for shouldOverrideUrlLoading
            return true;
        } else {
            // let WebView load the page!
            // activate loading animation screen
            uiManager.setLoading(true);
            // return value for shouldOverrideUrlLoading
            return false;
        }
    }

    // handle back button press
    public boolean goBack() {
        if (webView.getNavigator().canGoBack()) {
            webView.getNavigator().goBack();
            return true;
        }
        return false;
    }

    // load app startpage
    public void loadHome() {
        webView.load(Constants.WEBAPP_URL);
    }

    // load URL from intent
    public void loadIntentUrl(String url) {
        if (!url.equals("") && url.contains(Constants.WEBAPP_HOST)) {
            webView.load(url);
        } else {
            // Fallback
            loadHome();
        }
    }
}
